server-side-props.ts 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. import type { GetServerSidePropsContext, GetServerSidePropsResult } from 'next';
  2. import {
  3. SupportedAction,
  4. type SupportedActionType,
  5. } from '~/interfaces/activity';
  6. import type { IShareLinkHasId } from '~/interfaces/share-link';
  7. import {
  8. getServerSideCommonEachProps,
  9. getServerSideCommonInitialProps,
  10. getServerSideI18nProps,
  11. } from '../../common-props';
  12. import {
  13. getServerSideGeneralPageProps,
  14. getServerSideRendererConfigProps,
  15. isValidGeneralPageInitialProps,
  16. } from '../../general-page';
  17. import { addActivity } from '../../utils/activity';
  18. import { mergeGetServerSidePropsResults } from '../../utils/server-side-props';
  19. import { getPageDataForInitial } from './page-data-props';
  20. import type { Stage2InitialProps } from './types';
  21. const basisProps = {
  22. props: {
  23. isNotCreatable: true,
  24. isForbidden: false,
  25. isIdenticalPathPage: false,
  26. },
  27. };
  28. function getActivityAction(props: {
  29. isExpired: boolean | undefined;
  30. shareLink: IShareLinkHasId | undefined;
  31. }): SupportedActionType {
  32. if (props.isExpired) {
  33. return SupportedAction.ACTION_SHARE_LINK_EXPIRED_PAGE_VIEW;
  34. }
  35. if (props.shareLink == null) {
  36. return SupportedAction.ACTION_SHARE_LINK_NOT_FOUND;
  37. }
  38. return SupportedAction.ACTION_SHARE_LINK_PAGE_VIEW;
  39. }
  40. export async function getServerSidePropsForInitial(
  41. context: GetServerSidePropsContext,
  42. ): Promise<GetServerSidePropsResult<Stage2InitialProps>> {
  43. const [
  44. commonEachResult,
  45. commonInitialResult,
  46. generalPageResult,
  47. rendererConfigResult,
  48. i18nPropsResult,
  49. pageDataResult,
  50. ] = await Promise.all([
  51. getServerSideCommonEachProps(context),
  52. getServerSideCommonInitialProps(context),
  53. getServerSideGeneralPageProps(context),
  54. getServerSideRendererConfigProps(context),
  55. getServerSideI18nProps(context, ['translation']),
  56. getPageDataForInitial(context),
  57. ]);
  58. // Merge all results in a type-safe manner (using sequential merging)
  59. const mergedResult = mergeGetServerSidePropsResults(
  60. commonEachResult,
  61. mergeGetServerSidePropsResults(
  62. commonInitialResult,
  63. mergeGetServerSidePropsResults(
  64. generalPageResult,
  65. mergeGetServerSidePropsResults(
  66. rendererConfigResult,
  67. mergeGetServerSidePropsResults(
  68. i18nPropsResult,
  69. mergeGetServerSidePropsResults(pageDataResult, basisProps),
  70. ),
  71. ),
  72. ),
  73. ),
  74. );
  75. // Check for early return (redirect/notFound)
  76. if ('redirect' in mergedResult || 'notFound' in mergedResult) {
  77. return mergedResult;
  78. }
  79. const mergedProps = await mergedResult.props;
  80. // Type-safe props validation AFTER skipSSR is properly set
  81. if (!isValidGeneralPageInitialProps(mergedProps)) {
  82. throw new Error('Invalid merged props structure');
  83. }
  84. // Persist activity
  85. addActivity(context, getActivityAction(mergedProps));
  86. return mergedResult;
  87. }